package me.pplay.playtalk.protocol;

import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import me.pplay.playtalk.data.Globals;
import me.pplay.playtalk.protocol.bean.KeyValue;
import me.pplay.playtalk.protocol.bean.RspData;
import me.pplay.playtalk.protocol.bean.SendNode;
import me.pplay.playtalk.protocol.bean.TPBuddyinfo;
import me.pplay.playtalk.protocol.bean.TpNotiNode;
import me.pplay.playtalk.protocol.bean.TpNotiNode.tp_msg_node;
import me.pplay.playtalk.protocol.bean.TpPacket;
import me.pplay.playtalk.service.PlayTalkService;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;

public class TpChatRoom extends ProtocolPacket {
	public static final String BROADCASTACTION_TPCHATROOM = "me.pplay.playtalk.tpchatroom";
	public static final int CHATROOM_NETWORK_ERR = 200;
	public static final int CHATROOM_SESSIONID_ERR = 201;
	public static final int CHATROOM_AUTH_OK = 202;
	public static final int CHATROOM_AUTH_ERR = 203;
	public static final int CHATROOM_AUTH_TIMEOUT = 204;
	public static final int CHATROOM_REQ_OK = 205;
	public static final int CHATROOM_REQ_ERR = 206;
	public static final int CHATROOM_REQ_TIMEOUT = 207;
	public static final int CHATROOM_QUIT_OK = 208;
	public static final int CHATROOM_QUIT_ERR = 209;
	public static final int CHATROOM_QUIT_TIMEOUT = 210;
	public static final int CHATROOM_BUDDY_OK = 211;
	public static final int CHATROOM_BUDDY_ERR = 212;
	public static final int CHATROOM_BUDDY_TIMEOUT = 213;
	public static final int CHATROOM_MSG_OK = 214;

	private boolean isRun = false;
	private int skyid = -1;
	private boolean isneedKeepAlive = false;
	private int session_id = 0;
	private LinkedList<TPBuddyinfo> communityBuddiesList = new LinkedList<TPBuddyinfo>();
	private Map<Integer, DataCallBack> callBackMap = new HashMap<Integer, DataCallBack>();

	public void tp_setcallback(int cmd, DataCallBack callback) {
		callBackMap.put(cmd, callback);
	}

	public TpChatRoom() {
//		playTalkService			= new PlayTalkService();
		ProtocolList sendlist = new ProtocolList();
		setProtocolPacketSendList(sendlist);
		SET_TP_FLAG(TP_NEED_RECORD);
		setNeed_bytes((short) TP_PACKET_HDRLEN);
	}

	@Override
	public void tp_recvcb(int result, TpPacket pkt, SendNode node) {
		// TODO Auto-generated method stub
		switch (result) {
		case ProtocolType.TP_ERRCODE_ERR_SERVER:
		case ProtocolType.TP_ERRCODE_ERR_TPVERSION:
			// case TP_ERRCODE_ERR_SOCKETCLOSE:
		case ProtocolType.TP_ERRCODE_ERR_SOCKETDATAERR:
		case ProtocolType.TP_ERRCODE_ERR_SOCKET:
		case ProtocolType.TP_ERRCODE_ERR_SOCKETRECV:
		case ProtocolType.TP_ERRCODE_ERR_SOCKETSEND:
		case ProtocolType.TP_ERRCODE_ERR_SOCKETCONNECT:
			Callback(CHATROOM_NETWORK_ERR, null, null);
			break;
		case ProtocolType.TP_ERRCODE_ERR_TIMEOUT: {
			RspData rspdata = new RspData();
			rspdata.setSubid(node.getCmd());
			int subid = rspdata.getSubid();
			switch (subid) {
			case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH:
				Callback(CHATROOM_AUTH_TIMEOUT, rspdata, null);
				break;
			case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ:
				/** < . */
				Callback(CHATROOM_REQ_TIMEOUT, rspdata, null);
				break;
			case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT:
				/** < . */
				Callback(CHATROOM_QUIT_TIMEOUT, rspdata, null);
				break;
			case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS:
				/** < . */
				Callback(CHATROOM_BUDDY_TIMEOUT, rspdata, null);
				break;
			}
		}
			break;
		case ProtocolType.TP_ERRCODE_OK: {
			chatroom_packet_process(pkt);
		}
			break;
		}
	}

	@Override
	public void tp_keeplive() {
		// TODO Auto-generated method stub
		if (isneedKeepAlive)
			tp_chatroom_keepalive();
	}

	@Override
	public boolean tp_sendcb(int cmd, SendNode nodedata) {
		// TODO Auto-generated method stub
		TpPacket pkt = new TpPacket(); 
		pkt.setService(ProtocolType.ServerId.TP_SERVICE_CHATROOM);
		pkt.setSubid((short) nodedata.getCmd());
		pkt.setStatus((short) 0);
		pkt.setId(nodedata.getSession_id());
		Log.v("TpChatRoom", "tp_sendcb setSubid " + nodedata.getCmd()+ "  " + pkt.getSubid() );
		this.session_id = nodedata.getSession_id();
		return tp_send_packetex(pkt, null, this.skyid, nodedata.getData(), nodedata.getDatalen());
	}
 
	public void tp_chatroom_start(String url, int port, int skyid) {
		if (!isRun) {
			this.skyid = skyid;
			isRun = true;
			Log.v("TpChatRoom", "tp_chatroom_start" + url + skyid);
			this.tp_data_starturl(url, port);
		}
	}

	public void tp_chatroom_start(String url, int skyid) {
		if (!isRun) {
			this.skyid = skyid;
			isRun = true;
			String ip = new String(url);
			String[] iparray;
			iparray = ip.split(":");
			Log.v("TpChatRoom", "tp_chatroom_start" + url + skyid);
			this.tp_data_starturl(iparray[0], Integer.parseInt(iparray[1]));
		}
	}

	public void tp_chatroom_stop() {
		isRun = false;
		skyid = -1;
		isneedKeepAlive = false;
		communityBuddiesList.clear();
		callBackMap.clear();
		tp_data_stop();
	}

	private void tp_chatroom_senddata_cmn(int cmd, int timeout, byte[] data, DataCallBack callBack) {
		ProtocolList list = getProtocolPacketSendList();
		if (!isRun) {
			tp_chatroom_start(Globals.ChatRoomIpString, Globals.skyid);
		}
		list.tp_data_append_send(cmd, timeout, data, callBack);
	}

	public LinkedList<TPBuddyinfo> tp_chatroom_get_buddieslist() {
		Log.v("TpChatRoom", "tp_chatroom_get_buddieslist");
		if (communityBuddiesList.size() > 0)
			return communityBuddiesList;
		else
			return null;
	}
	
	public void tp_chatroom_auth(String token, DataCallBack callback) {
		tp_setcallback(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH, callback);
		tp_chatroom_auth(token);
	}

	public void tp_chatroom_auth(String token) {// 回复
		Log.v("TpChatRoom", "tp_chatroom_auth" + token);
		byte[] data = null;
		Map<String, String> map = new HashMap<String, String>();
		map.put(ProtocolType.Key.TP_TAG_token, token);
		data = tp_packet_putdata(map);
		tp_chatroom_senddata_cmn(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH, ProtocolType.TP_TIMOUT, data, callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH));

	}
	public void tp_chatroom_get_friends(int gid, int gnum, int gtotal, DataCallBack callback) {// 回复
		tp_setcallback(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS, callback);
		tp_chatroom_get_friends(gid, gnum, gtotal);
	}
	public void tp_chatroom_get_friends(int gid, int gnum, int gtotal) {// 回复
		Log.v("TpChatRoom", "tp_chatroom_get_friends " + gid);
		byte[] data = null;
		Map<String, String> map = new HashMap<String, String>();
		map.put(ProtocolType.Key.TP_TAG_gid, "" + gid);
		data = tp_packet_putdata(map);
		tp_chatroom_senddata_cmn(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS, ProtocolType.TP_TIMOUT, data, callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS));
	}

	public void tp_chatroom_req_addchatroom(String alias, int skyid, int gid, DataCallBack callback) {// 回复
		tp_setcallback(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ, callback);
		tp_chatroom_req_addchatroom(alias, skyid, gid);
	}

	public void tp_chatroom_req_addchatroom(String alias, int skyid, int gid) {// 回复
		Log.v("TpChatRoom", "tp_chatroom_req_addchatroom" + gid);
		byte[] data = null;
		Map<String, String> map = new HashMap<String, String>();
		map.put(ProtocolType.Key.TP_TAG_gid, "" + gid);
		map.put(ProtocolType.Key.TP_TAG_alias, "" + alias);
		data = tp_packet_putdata(map);
		tp_chatroom_senddata_cmn(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ, ProtocolType.TP_TIMOUT, data, callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ));

	}

	public void tp_chatroom_req_removechatroom(String alias, int skyid, int gid, DataCallBack callback) {// 回复
		tp_setcallback(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT, callback);
		tp_chatroom_req_removechatroom(alias, skyid, gid);
	}

	public void tp_chatroom_req_removechatroom(String alias, int skyid, int gid) {// 回复
		Log.v("TpChatRoom", "tp_chatroom_req_removechatroom" + gid);
		byte[] data = null;
		Map<String, String> map = new HashMap<String, String>();
		map.put(ProtocolType.Key.TP_TAG_gid, "" + gid);
		map.put(ProtocolType.Key.TP_TAG_alias, "" + alias);
		data = tp_packet_putdata(map);
		tp_chatroom_senddata_cmn(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT, ProtocolType.TP_TIMOUT, data, callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT));

	}

	public void tp_chatroom_send_im(String alias, int gid, String message) {// 不回复
		Log.v("TpChatRoom", "tp_chatroom_send_im" + gid + message);
		byte[] data = null;
		Map<String, String> map = new HashMap<String, String>();
		map.put(ProtocolType.Key.TP_TAG_gid, "" + gid);
		map.put(ProtocolType.Key.TP_TAG_alias, "" + alias);
		map.put(ProtocolType.Key.TP_TAG_msg, "" + message);
		data = tp_packet_putdata(map);
		tp_chatroom_senddata_cmn(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_SENDIM, 0, data, null);
	}

	private void tp_chatroom_keepalive() {// 不回复
		Log.v("TpChatRoom", "TP_SUBSERVICE_CHATROOM_KEEPALIVE");
		tp_chatroom_senddata_cmn(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_KEEPALIVE, 0, null, null);

	}

	private void chatroom_packet_notification_process(TpPacket pkt) {
		int subid;
		RspData rspdata = new RspData();
		rspdata.setSubid(pkt.getSubid());
		subid = pkt.getSubid();
		// common_data.session_id = pkt->id;
		TpNotiNode noti_node = new TpNotiNode();
		noti_node.setType(subid);
		LinkedList<KeyValue> list = pkt.getList();
		Log.v("TpChatRoom", "chatroom_packet_notification_process");
		switch (subid) {

		case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_MSG: {// 消息(群消息，点对点消息)
			int curlan = -1;
			int gtype = -1;
			tp_msg_node node = noti_node.new tp_msg_node();

			for (KeyValue kv : list) {
				String key = kv.key;
				String value =  kv.value;
				if (key.equals(ProtocolType.Key.TP_TAG_skyid)) {
					if (node.getSkyid() != -1) {
						noti_node.setMsg_node(node);
						Callback(CHATROOM_MSG_OK, rspdata, noti_node);
					}
					node.setSkyid(Integer.parseInt(value));
				} else if (key.equals(ProtocolType.Key.TP_TAG_msg))
					node.setMsg(value);
				else if (key.equals(ProtocolType.Key.TP_TAG_gtype))
					node.setMsgtype(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_gid))
					node.setGid(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_alias))
					node.setAlias(value);
			}
			if (node.getSkyid() != -1) {
				noti_node.setMsg_node(node);
				Callback(CHATROOM_MSG_OK, rspdata, noti_node);
			}
		}
			break;
		case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS: {// 好友列表,异步传输
			communityBuddiesList.clear();
			TPBuddyinfo b = new TPBuddyinfo();
			for (KeyValue kv : list) {
				String key = kv.key;
				String value =  kv.value;
				if (key.equals(ProtocolType.Key.TP_TAG_skyid)) {
					if (b.getSkyid() != -1){
						communityBuddiesList.add(b);
//						Callback(CHATROOM_BUDDY_OK, rspdata, b);
					}
					b.setSkyid(Integer.parseInt(value));
				} else if (key.equals(ProtocolType.Key.TP_TAG_gid))
					rspdata.setProto_data(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_user))
					b.setName(value);
				else if (key.equals(ProtocolType.Key.TP_TAG_alias))
					b.setAlias(value);
				else if (key.equals(ProtocolType.Key.TP_TAG_salias))
					b.setServer_alias(value);
				else if (key.equals(ProtocolType.Key.TP_TAG_icon))
					b.setAvatarid(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_bstatus))
					b.setStatus(Integer.parseInt(value));
			}
			if (b.getSkyid() != -1){
				communityBuddiesList.add(b);
				Callback(CHATROOM_BUDDY_OK, rspdata, b);
			}
		}
			break;
		}
		return;
	}

	private void chatroom_packet_process(TpPacket pkt) {
		int subid;
		RspData rspdata = new RspData();
		rspdata.setSubid(pkt.getSubid());
		if (pkt.getService() != ProtocolType.ServerId.TP_SERVICE_CHATROOM) {
			Callback(CHATROOM_SESSIONID_ERR, rspdata, null);
			return;
		}
		if (pkt.getSubid() == ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS || pkt.getSubid() == ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_MSG) {
			chatroom_packet_notification_process(pkt);
			return;
		}

		if (pkt.getId() != this.session_id) {
			return;
		}
		LinkedList<KeyValue> list = pkt.getList();
		subid = pkt.getSubid();
		switch (subid) {
		case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH:/** < . */
		{
			for (KeyValue kv : list) {
				String key = kv.key;
				String value =  kv.value;
				if (key.equals(ProtocolType.Key.TP_TAG_err))
					rspdata.setErrcode(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_errstr))
					rspdata.setString(value);
			}
			if (rspdata.getErrcode() == ProtocolType.TP_ERRCODE_OK) {
				Callback(CHATROOM_AUTH_OK, rspdata, null);
				isneedKeepAlive = true;
			} else {
				Callback(CHATROOM_AUTH_ERR, rspdata, null);
			}

		}
			break;
		case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ: {
			for (KeyValue kv : list) {
				String key = kv.key;
				String value =  kv.value;
				if (key.equals(ProtocolType.Key.TP_TAG_err))
					rspdata.setErrcode(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_errstr))
					rspdata.setString(value);
			}
			if (rspdata.getErrcode() == ProtocolType.TP_ERRCODE_OK) {
				Callback(CHATROOM_REQ_OK, rspdata, null);
			} else {
				Callback(CHATROOM_REQ_ERR, rspdata, null);
			}
		}
			break;
		case ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT:/** < . */
		{
			for (KeyValue kv : list) {
				String key = kv.key;
				String value =  kv.value;
				if (key.equals(ProtocolType.Key.TP_TAG_err))
					rspdata.setErrcode(Integer.parseInt(value));
				else if (key.equals(ProtocolType.Key.TP_TAG_errstr))
					rspdata.setString(value);
			}
			if (rspdata.getErrcode() == ProtocolType.TP_ERRCODE_OK) {
				Callback(CHATROOM_QUIT_OK, rspdata, null);
			} else {
				Callback(CHATROOM_QUIT_ERR, rspdata, null);
			}
		}
			break;
		// TP_SUBSERVICE_CONFERENCE_CREATE
		}
	}

	private void CallbackBroadCast(int result, RspData resultdata, Object obj) {
		Log.v("TpChatRoom", "CallbackBroadCast = " + result);
		Message msg = new Message();
		msg.what	= result;
		Bundle bundle = new Bundle();
		bundle.putInt("result", result);
		bundle.putSerializable("resultdata", resultdata);
		bundle.putSerializable("object", (Serializable) obj);
		msg.setData(bundle);
		PlayTalkService.getInstance().serviceHandler.sendMessage(msg);
//		Intent intent = new Intent();
//		if(result == CHATROOM_MSG_OK)
//			intent.setAction(PlayTalkService.COMMUNITY_CHAT_BRODCASE);
//		else
//			intent.setAction(BROADCASTACTION_TPCHATROOM);
//		intent.putExtra("result", result);
//		intent.putExtra("resultdata", resultdata);
//		intent.putExtra("object", (Serializable) obj);
//		context.sendBroadcast(intent);
	}

	private void Callback(int result, RspData resultdata, Object obj) {
		Log.v("TpChatRoom", "Callback = " + result);
		switch (result) {
		case CHATROOM_NETWORK_ERR: {
			ProtocolList list = getProtocolPacketSendList();
			if (list != null) {
				SendNode sendnode = list.tp_data_firstnode();
				if (sendnode!=null&&sendnode.getCallBack() != null) {
					sendnode.getCallBack().Callback(result, resultdata, obj);
				}
			}
		}
			break;
		case CHATROOM_AUTH_OK:
		case CHATROOM_AUTH_ERR:
		case CHATROOM_AUTH_TIMEOUT:
			if (callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH) != null) {
				callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_AUTH).Callback(result, resultdata, obj);
				return;
			}
			break;
		case CHATROOM_REQ_OK:
		case CHATROOM_REQ_ERR:
		case CHATROOM_REQ_TIMEOUT:
			if (callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ) != null) {
				callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_REQ).Callback(result, resultdata, obj);
				return;
			}
			break;
		case CHATROOM_QUIT_OK:
		case CHATROOM_QUIT_ERR:
		case CHATROOM_QUIT_TIMEOUT:
			if (callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT) != null) {
				callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_QUIT).Callback(result, resultdata, obj);
				return;
			}
			break;
		case CHATROOM_BUDDY_OK:
		case CHATROOM_BUDDY_ERR:
		case CHATROOM_BUDDY_TIMEOUT:
			if (callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS) != null) {
				callBackMap.get(ProtocolType.ChatRoomType.TP_SUBSERVICE_CHATROOM_GETFRIENDS).Callback(result, resultdata, obj);
				return;
			}
			break;
		}
		CallbackBroadCast(result, resultdata, obj);
	}

}
